package com.sky.utils;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.sky.properties.BaiduMapsProperties;
import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GeodeticCalculator;
import org.gavaghan.geodesy.GeodeticCurve;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriUtils;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * TODO
 *
 * @Author Yjr
 * @Date 2025/5/28 20:23
 */
@Component
public class BaiduMapsUtil {

    private static String strUrl = "https://api.map.baidu.com/geocoding/v3?";
    @Autowired
    private BaiduMapsProperties baiduMapsProperties;

    /**
     * 默认ak
     * 选择了ak，使用IP白名单校验：
     * 根据您选择的AK已为您生成调用代码
     * 检测到您当前的ak设置了IP白名单校验
     * 您的IP白名单中的IP非公网IP，请设置为公网IP，否则将请求失败
     * 请在IP地址为xxxxxxx的计算发起请求，否则将请求失败
     */
    public  Double getDistance(String address ) throws Exception {
        if (!StringUtils.hasLength(address)){
            return null;
        }

        Map<String, String> param = new LinkedHashMap<String, String>();
        param.put("address", address);
        param.put("output", "json");
        param.put("ak", baiduMapsProperties.getAk());
        param.put("callback", "showLocation");


        StringBuffer queryString = new StringBuffer();
        queryString.append(strUrl);
        for (Map.Entry<?, ?> pair : param.entrySet()) {
            queryString.append(pair.getKey() + "=");
            //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
            //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
            queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
        }

        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }

        java.net.URL url = new URL(queryString.toString());
        System.out.println(queryString.toString());
        URLConnection httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.connect();

        InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
        BufferedReader reader = new BufferedReader(isr);
        StringBuffer buffer = new StringBuffer();
        String line;
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
        reader.close();
        isr.close();

        // 找到第一个 { 的位置
        int start = buffer.indexOf("{");
        // 找到最后一个 } 的位置
        int end = buffer.lastIndexOf("}");

        String jsonStr = buffer.substring(start, end + 1);

        JSONObject location = JSONUtil.parseObj(jsonStr).getJSONObject("result").getJSONObject("location");

        JSONObject defaultLocation = getDefaultLocation();
        Double lat1 = defaultLocation.getDouble("lat");
        Double lng1 = defaultLocation.getDouble("lng");
        Double lat2 = location.getDouble("lat");
        Double lng2 = location.getDouble("lng");
        GeodeticCurve geoCurve = new GeodeticCalculator().calculateGeodeticCurve(
                Ellipsoid.Sphere,
                new GlobalCoordinates(lat1,lng1 ),
                new GlobalCoordinates(lat2,lng2 )
        );
        return geoCurve.getEllipsoidalDistance();
    }

    private  JSONObject getDefaultLocation() throws Exception {
        Map<String, String> defaultParam = new LinkedHashMap<String, String>();
        defaultParam.put("address", baiduMapsProperties.getAddress());
        defaultParam.put("output", "json");
        defaultParam.put("ak", baiduMapsProperties.getAk());
        defaultParam.put("callback", "showLocation");

        StringBuffer queryString = new StringBuffer();
        queryString.append(strUrl);
        for (Map.Entry<?, ?> pair : defaultParam.entrySet()) {
            queryString.append(pair.getKey() + "=");
            //    第一种方式使用的 jdk 自带的转码方式  第二种方式使用的 spring 的转码方法 两种均可
            //    queryString.append(URLEncoder.encode((String) pair.getValue(), "UTF-8").replace("+", "%20") + "&");
            queryString.append(UriUtils.encode((String) pair.getValue(), "UTF-8") + "&");
        }

        if (queryString.length() > 0) {
            queryString.deleteCharAt(queryString.length() - 1);
        }

        java.net.URL url = new URL(queryString.toString());
        System.out.println(queryString.toString());
        URLConnection httpConnection = (HttpURLConnection) url.openConnection();
        httpConnection.connect();

        InputStreamReader isr = new InputStreamReader(httpConnection.getInputStream());
        BufferedReader reader = new BufferedReader(isr);
        StringBuffer buffer = new StringBuffer();
        String line;
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
        reader.close();
        isr.close();

        // 找到第一个 { 的位置
        int start = buffer.indexOf("{");
        // 找到最后一个 } 的位置
        int end = buffer.lastIndexOf("}");

        String jsonStr = buffer.substring(start, end + 1);

        JSONObject jsonObject = JSONUtil.parseObj(jsonStr);
        return jsonObject.getJSONObject("result").getJSONObject("location");
    }
}
